package com.grandtech.insurance.common.bean;

import com.google.gson.GsonBuilder;
import com.grandtech.insurance.common.core.utils.CustomPointSerializer;
import com.mapbox.geojson.BoundingBox;
import com.mapbox.geojson.Feature;
import com.mapbox.geojson.FeatureCollection;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.gson.BoundingBoxSerializer;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by zy on 2019/1/10.
 * featureSet里的数据必须是同一个sourceId的
 */

public class FeatureSet extends FeatureCollection implements Serializable {

    private String layerId;

    private String sourceId;

    private String geoJson;

    private String[] keyWords;


    public FeatureSet() {
    }

    private FeatureSet(String geoJson) {
        this.geoJson = geoJson;
    }

    public String getGeoJson() {
        return geoJson;
    }

    public FeatureSet setGeoJson(String geoJson) {
        this.geoJson = geoJson;
        return this;
    }

    public String getLayerId() {
        return layerId;
    }

    public FeatureSet setLayerId(String layerId) {
        this.layerId = layerId;
        return this;
    }

    public String getSourceId() {
        return sourceId;
    }

    public FeatureSet setSourceId(String sourceId) {
        this.sourceId = sourceId;
        return this;
    }

    public String[] getKeyWords() {
        return keyWords;
    }

    public FeatureSet setKeyWords(String[] keyWords) {
        this.keyWords = keyWords;
        return this;
    }

    @Override
    public String type() {
        return null;
    }

    @Override
    public BoundingBox bbox() {
        return null;
    }

    @Override
    public List<Feature> features() {
        FeatureCollection featureCollection = FeatureCollection.fromJson(geoJson);
        return featureCollection == null ? null : featureCollection.features();
    }

    public FeatureSet append(Feature feature) {
        List<Feature> features = new ArrayList<>();
        FeatureCollection append = FeatureCollection.fromFeature(feature);
        FeatureCollection origin = FeatureCollection.fromJson(geoJson);
        features.addAll(origin.features());
        features.addAll(append.features());
        this.geoJson = toJson(FeatureCollection.fromFeatures(features));
        return this;
    }

    public FeatureSet append(Feature[] feature) {
        List<Feature> features = new ArrayList<>();
        FeatureCollection append = FeatureCollection.fromFeatures(feature);
        FeatureCollection origin = FeatureCollection.fromJson(geoJson);
        features.addAll(origin.features());
        features.addAll(append.features());
        this.geoJson = toJson(FeatureCollection.fromFeatures(features));
        return this;
    }

    public FeatureSet append(List<Feature> feature) {
        List<Feature> features = new ArrayList<>();
        FeatureCollection append = FeatureCollection.fromFeatures(feature);
        FeatureCollection origin = FeatureCollection.fromJson(geoJson);
        features.addAll(origin.features());
        features.addAll(append.features());
        this.geoJson = toJson(FeatureCollection.fromFeatures(features));
        return this;
    }

    public FeatureSet append(String json) {
        List<Feature> features = new ArrayList<>();
        FeatureCollection append = FeatureCollection.fromJson(json);
        FeatureCollection origin = FeatureCollection.fromJson(geoJson);
        features.addAll(origin.features());
        features.addAll(append.features());
        this.geoJson = toJson(FeatureCollection.fromFeatures(features));
        return this;
    }

    /**
     * @return 该方法会造成坐标精度的丢失，不建议使用
     */
    @Override
    public String toJson() {
        GsonBuilder gson = new GsonBuilder();
        gson.registerTypeAdapter(Point.class, new CustomPointSerializer(9));
        gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxSerializer());
        return gson.create().toJson(this);
    }

    /**
     * 自定义FeatureCollection 转json 防止坐标精度丢失
     *
     * @param collection
     * @return
     */
    public static String toJson(FeatureCollection collection) {
        GsonBuilder gson = new GsonBuilder();
        gson.registerTypeAdapter(Point.class, new CustomPointSerializer(9));
        gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxSerializer());
        return gson.create().toJson(collection);
    }


    /**
     * *********************************************************************************************
     */

    public static FeatureSet fromJson(String json) {
        FeatureCollection featureCollection = FeatureCollection.fromJson(json);
        if (featureCollection == null) return null;
        String _json = toJson(featureCollection);
        FeatureSet featureSet = new FeatureSet(_json);
        return featureSet;
    }

    public static FeatureSet fromFeatures(Feature[] features) {
        FeatureCollection featureCollection = FeatureCollection.fromFeatures(features);
        if (featureCollection == null) return null;
        String _json = toJson(featureCollection);
        FeatureSet featureSet = new FeatureSet(_json);
        return featureSet;
    }

    public static FeatureSet fromFeatures(List<Feature> features) {
        FeatureCollection featureCollection = FeatureCollection.fromFeatures(features);
        if (featureCollection == null) return null;
        String _json = toJson(featureCollection);
        FeatureSet featureSet = new FeatureSet(_json);
        return featureSet;
    }


    public static FeatureSet fromFeature(Feature feature) {
        FeatureCollection featureCollection = FeatureCollection.fromFeature(feature);
        if (featureCollection == null) return null;
        String _json = toJson(featureCollection);
        FeatureSet featureSet = new FeatureSet(_json);
        return featureSet;
    }

    /**
     * *********************************************************************************************
     */

    public static List<FeatureSet> convert2FeatureSets(Map<String, FeatureSet> featureSetMap) {
        if (featureSetMap == null) return null;
        List<FeatureSet> list = new ArrayList<>();
        for (String name : featureSetMap.keySet()) {
            list.add(featureSetMap.get(name));
        }
        return list;
    }

}
